# -*- coding: utf-8 -*-
"""
  @Time    : 2024/3/1 17:59
  @Author  : 
  @email   : 
  @File    : worker.py
"""

from flask import current_app
from lib.docker_manage import DockerEngine
from lib.tools import dict_merge, SerializeData, resolve_with_specific_dns
import re
import os


def get_containers_info(base_url_list):
    container_data = {}
    for base_url in base_url_list:
        # current_app.logger.info("base_url: %s" % base_url)
        try:
            docker_client = DockerEngine(base_url=base_url)
            container_data = dict_merge(
                container_data,
                docker_client.container_info())
        except Exception as e:
            current_app.logger.error(e)
    return container_data


def persistent_containers_info():
    """
    持久化容器信息调度任务
    :return:
    """
    data_dir = os.path.join(current_app.config.get('BASE_DIR'), 'data')

    prod_base_url_list = current_app.config.get('BASE_URL_PROD')
    prod_fp = os.path.join(data_dir, current_app.config.get('PROD_INFO_CONF'))

    test_base_url_list = current_app.config.get('BASE_URL_TEST')
    test_fp = os.path.join(data_dir, current_app.config.get('TEST_INFO_CONF'))

    # 生产容器信息持久化到本地
    current_app.logger.info("执行生产环境容器信息持久化")
    prod_obj = SerializeData(fp=prod_fp)
    prod_info_dict = get_containers_info(prod_base_url_list)
    prod_obj.dump_file(prod_info_dict)

    # 测试容器信息持久化到本地
    current_app.logger.info("执行测试环境容器信息持久化")
    test_obj = SerializeData(fp=test_fp)
    test_info_dict = get_containers_info(test_base_url_list)
    test_obj.dump_file(test_info_dict)


def persistent_containers_info_single():
    """
    持久化单路容器信息调度任务
    :return:
    """
    data_dir = os.path.join(current_app.config.get('BASE_DIR'), 'data')
    prod_base_url_list = current_app.config.get('BASE_URL_PROD')
    prod_fp = os.path.join(
        data_dir,
        current_app.config.get('PROD_INFO_SINGLE_CONF'))

    containers_dict = {}
    containers_key_list = []
    for endpoint_url in prod_base_url_list:
        current_app.logger.info("endpoint_url: %s" % endpoint_url)
        matchObj = re.match(r'tcp://(.*):2375', endpoint_url, re.S)
        node_name = matchObj.group(1)
        try:
            docker_client = DockerEngine(base_url=endpoint_url)
            containers_dict[node_name] = docker_client.container_info()
            containers_key_list.append(
                set(docker_client.container_info().keys()))
        except Exception as e:
            current_app.logger.error(e)

    intersection_key = set.intersection(*containers_key_list)
    for node_key in list(containers_dict.keys()):
        for key in list(containers_dict[node_key].keys()):
            if key in intersection_key:
                containers_dict[node_key].pop(key)

    current_app.logger.info("执行生产环境单路容器信息持久化")
    prod_obj = SerializeData(fp=prod_fp)
    prod_obj.dump_file(containers_dict)


def domainname_to_hosts():
    """
    将指定域名解析记录添加到hosts文件中,避免dns解析失败问题
    :return:
    """
    DOMAIN_FILE = os.path.join(current_app.config.get('BASE_DIR'), 'DOMAINNAME')
    HOSTS_FILE = '/etc/hosts'

    with open(DOMAIN_FILE, 'r') as f:
        domain_fr = f.readlines()

    add_domains = []
    for domain in domain_fr:
        add_flag = 1
        update_flag = 0
        modified_lines = []
        domain_name = domain.strip()
        # 空行跳过
        if domain_name == "":
            continue
        # 域名解析结果列表
        ip_list = resolve_with_specific_dns(domain_name)
        if not ip_list:
            continue
        current_app.logger.info("domain_name: %s" % domain_name)
        current_app.logger.info("解析结果: %s" % ip_list)
        with open(HOSTS_FILE, 'r') as f:
            for line in f:
                # 去除换行符，转成列表
                line_list = line.strip().split(' ')
                if domain_name in line_list:
                    add_flag = 0
                    ip_addr = line_list[0]
                    current_app.logger.info("add_flag: %d" % add_flag)
                    current_app.logger.info("hosts记录: %s" % ip_addr)
                    if ip_addr not in ip_list:
                        # 替换
                        update_flag = 1
                        current_app.logger.info("update_flag: %d" % update_flag)
                        current_app.logger.info("1.执行变更域名记录: %s" % domain_name)
                        new_line = f'{ip_list[0]} {domain_name}\n'
                        modified_line = line.replace(line, new_line)
                    else:
                        modified_line = line
                else:
                    modified_line = line
                modified_lines.append(modified_line)

            if add_flag:
                current_app.logger.info("2.执行新增域名记录: %s" % domain_name)
                new_record = "%s %s\n" % (ip_list[0], domain_name)
                add_domains.append(new_record)

        # 更新解析记录
        if update_flag:
            with open(HOSTS_FILE, 'w') as f:
                for line in modified_lines:
                    f.write(line)

    # 添加新记录
    if add_domains:
        with open(HOSTS_FILE, 'a') as f:
            for line in add_domains:
                f.write(line)
